/*
 *  Copyright 2011 Mark Eschbach
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 * $HeadURL: https://meschbach.com/svn/software/mee-utils/trunk/psi-util/src/main/java/com/meschbach/psi/util/RESTClient.java $
 * $Id: RESTClient.java 2844 2011-01-28 05:12:03Z meschbach $
 */
package com.meschbach.psi.util;

import com.meschbach.psi.PSIException;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;

/**
 *
 * @author "Mark Eschbach" &lt;meschbach@gmail.com&gt;
 * @since 1.1.0
 * @version 1.0.0
 */
public class RESTClient {

    public enum HttpStatusCode {

        Ok(200),
        Created(201),
        NoContent(204),
        ResetContent(205),
        TemporaryRedirect(307),
        BadRequest(400),
        Unauthorized(401),
        Forbidden(403),
        NotFound(404),
        ServerError(500),
        ServiceUnavailable(503);
        int code;

        private HttpStatusCode(int code) {
            this.code = code;
        }

        public static HttpStatusCode getCode(int statusCode) {
            for (HttpStatusCode code : HttpStatusCode.values()) {
                if (code.code == statusCode) {
                    return code;
                }
            }
            throw new RuntimeException("Unknown code " + statusCode + "; please patch to expand");
        }
    }

    public static void assertGetStatus(String url, HttpStatusCode expectedCode) {
        /*
         * Issue the request
         */
        HttpClient client = new DefaultHttpClient();
        try {
            /*
             * Construct and issue request
             */
            HttpGet get = new HttpGet(url);
            HttpResponse response = client.execute(get);
            /*
             * Ensure the response code is as expected
             */
            HttpStatusCode responseCode = HttpStatusCode.getCode(response.getStatusLine().getStatusCode());
            assert responseCode == expectedCode : "Expected status code " + expectedCode + ", got " + responseCode;
        } catch (Throwable t) {
            throw new RuntimeException(t);
        } finally {
            client.getConnectionManager().shutdown();
        }
    }

    public static void assertPutStatus(String url, String entity, HttpStatusCode expectedCode) {
        /*
         * Issue the request
         */
        HttpClient client = new DefaultHttpClient();
        try {
            /*
             * Construct and issue request
             */
            HttpPut put = new HttpPut(url);
            put.setEntity(new StringEntity(entity));
            HttpResponse response = client.execute(put);
            /*
             * Ensure the response code is as expected
             */
            HttpStatusCode responseCode = HttpStatusCode.getCode(response.getStatusLine().getStatusCode());
            assert responseCode == expectedCode : "Expected status code " + expectedCode + ", got " + responseCode;
        } catch (Throwable t) {
            throw new RuntimeException(t);
        } finally {
            client.getConnectionManager().shutdown();
        }
    }

    public static void assertGet(String url, String expectedEntity) {
        assertGet(url, HttpStatusCode.Ok, expectedEntity);
    }

    public static void assertGet(String url, HttpStatusCode expectedCode, String expectedEntity) {
        /*
         * Issue the request
         */
        HttpClient client = new DefaultHttpClient();
        try {
            /*
             * Construct and issue request
             */
            HttpGet get = new HttpGet(url);
            HttpResponse response = client.execute(get);
            /*
             * Ensure the response code is as expected
             */
            HttpStatusCode responseCode = HttpStatusCode.getCode(response.getStatusLine().getStatusCode());
            assert responseCode == expectedCode : "Expected status code " + expectedCode + ", got " + responseCode;
            /*
             * Issue the
             */
            String result = Util.convertToString(response.getEntity().getContent());
            assert expectedEntity.equals(result) : "Expected response <" + expectedEntity + ">, recieved <" + result + ">";
        }catch(PSIException psie){
            throw new RuntimeException(psie);
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        } catch (AssertionError ae) {
            throw ae;
        } finally {
            client.getConnectionManager().shutdown();
        }
    }
}
